#include <iostream>

template <typename Elem>
class FreeList {
public:
    FreeList(const Elem& elem, FreeList *next = nullptr);
    FreeList(FreeList *next = nullptr);
    void* operator new(size_t);
    void operator delete(void *);

private:
    static FreeList<Elem>* free_list;
    Elem m_elem;
    FreeList* next;
};

template <typename Elem>
FreeList<Elem>* FreeList<Elem>::free_list = nullptr;

template <typename Elem>
FreeList<Elem>::FreeList(const Elem& elem, FreeList *next) : m_elem(elem), next(next) {}

template <typename Elem>
FreeList<Elem>::FreeList(FreeList *next) : next(next) {}

template <typename Elem>
void* FreeList<Elem>::operator new(size_t) {
    if (free_list == nullptr)
        return ::new FreeList();

    FreeList<Elem>* tmp = free_list;
    free_list = free_list->next;
    return tmp;
}

template <typename Elem>
void FreeList<Elem>::operator delete(void* ptr) {
    FreeList<Elem>* tmp = reinterpret_cast<FreeList<Elem>*>(ptr);
    tmp->next = free_list;
    free_list = tmp;
}

int main(int argc, const char **argv) {
    FreeList<int>* tmp = new FreeList<int>();
    (void)tmp;
    return 0;
}
